var AttendanceDetail = function () {
  var AttendanceDetailModel = function (detail, type) {
    BaseModel.call(this);

    var self = this;
    var fn = {
      initData: function (detail, type) {
        var deptWork = this.getDeptWorkshop(detail);
        self.deptWork = deptWork;
        self.userName = detail.userName;
        self.type = type;

        var baseTime = detail.baseTime;
        if (type === 'leave') {
          var arr = baseTime.split('-');
          self.startTime = this.getTimeStr(arr[0], 'YYYY-MM-DD HH:mm');
          self.endTime = this.getTimeStr(arr[1], 'YYYY-MM-DD HH:mm');
        } else {
          self.baseTime = this.getTimeStr(baseTime);
        }
      },

      getDeptWorkshop: function (detail) {
        var deptWork = [];
        var deptName = detail.deptName;
        if (!SysUtil.isEmpty(deptName)) {
          deptWork.push(deptName);
        }
        var workshopName = detail.workshopName;
        if (!SysUtil.isEmpty(workshopName)) {
          deptWork.push(workshopName);
        }
        return deptWork.join('-');
      },

      getTimeStr: function (time, formater) {
        if (SysUtil.isEmpty(time)) {
          return '';
        }

        time = Number(time);
        if (_.isNaN(time)) {
          return '';
        }

        if (formater === undefined) {
          formater = 'HH:mm';
        }

        return moment(time).format(formater);
      }
    };

    this.getObject = function () {
      var type = this.type;
      var time;
      if (type === 'leave') {
        var startTime = this.startTime;
        var endTime = this.endTime;
        time = `${startTime}至${endTime}`;
      } else {
        time = this.baseTime;
      }
      return `${this.userName}(${time})`;
    };

    fn.initData(detail, type)
  }

  var tableConfigs = [{
    name: '请假',
    field: 'leave',
  }, {
    name: '缺卡',
    field: 'lack',
  }, {
    name: '迟到',
    field: 'late',
  }, {
    name: '早退',
    field: 'early',
  }];

  var template = /* html */ `
    <div class="attendance-detail">
      <slot></slot>
      <div class="attendance-detail-search clearfix">
        <div>
          <el-select filterable clearable v-model="search.deptWork" style="width:250px" size="mini" placeholder="请选择车间-部门"
            @change="searchData">
            <el-option v-for="(deptWork,index) in deptWorkList" :key="'deptWork_'+deptWork" :value="deptWork"></el-option>
          </el-select>
        </div>
        <div>
          <sys-autocomplete open-all-dropdown v-model="search.userName" size="mini" :options="userNameList" placeholder="请输入姓名"
            @change="searchData">
          </sys-autocomplete>
        </div>
      </div>
      <div v-if="detailList!==null" ref="attendanceContent" class="attendance-detail-content">
        <table ref="attendanceTable" cellspacing="0" cellpadding="0" :style="getTableStyle()">
          <thead>
            <tr>
              <td>部门-车间</td>
              <td v-for="config in configs" :key="config.field">
                {{config.name}}
              </td>
            </tr>
          </thead>
          <tbody>
            <template v-for="(detail,groupIndex) in detailList">
            <template v-for="(obj,dataIndex) in detail.data">
              <tr :key="'detail_'+groupIndex+'_'+dataIndex">
                <td v-if="dataIndex===0" :rowspan="detail.data.length">{{detail.deptWork}}</td>
                <td v-for="config in configs" :key="config.field">
                  {{obj[config.field]}}
                </td>
              </tr>
            </template>
            </template>
          </tbody>
        </table>
      </div>
    </div>
  `;

  return {
    mixins: [boardRunningMixin],

    props: {
      attendances: {
        type: Array,
        required: true
      },
      data: {
        type: Object,
        required: true
      },
      zoom: {
        type: Number,
        default: 1
      }
    },

    watch: {
      changeData: function (newData, oldData) {
        if (newData.data !== oldData.data) {
          this.setAttendanceDetailObj();
          this.toSearchData();
          return;
        }

        this.resetTable();
      },

      zoom: function () {
        this.clearTimeoutList();
        var self = this;
        this.$nextTick(function () {
          self.changeRowIndex(true);
          self.changeColIndex(true);
        });
        this.boardRunning();
      }
    },

    computed: {
      changeData: function () {
        return {
          data: this.data,
          rowIndex: this.rowIndex,
          colIndex: this.colIndex
        };
      }
    },

    data: function () {
      return {
        rowIndex: 0,
        colIndex: 0,
        attendanceDetailObj: this.getAttendanceDetailObj(),
        searchDetailList: [],
        detailList: null,
        configs: tableConfigs,
        search: {
          deptWork: '',
          userName: ''
        },
        deptWorkList: [],
        userNameList: []
      };
    },

    created: function () {
      this.toSearchData();
    },

    mounted: function () {
      this.setDropdownList();
      this.boardRunning();

      var self = this;
      $(this.$el).resize(function () {
        self.clearTimeoutList();
        self.changeRowIndex(true);
        self.changeColIndex(true);
        self.boardRunning();
      });
    },

    methods: {
      boardRunning: function () {
        this.clearTimeoutList();
        this.tableRunning();
      },

      setDropdownList: function () {
        var detailObj = this.attendanceDetailObj;
        var detailList = _.values(detailObj);
        var userNameList = [];

        var fields = ['early', 'late', 'leave', 'lack'];
        for (var i = 0; i < detailList.length; i++) {
          var detail = detailList[i];
          for (var j = 0; j < fields.length; j++) {
            var field = fields[j];
            var list = detail[field];
            if (SysUtil.isEmpty(list)) {
              continue;
            }

            var userNames = _.map(list, 'userName');
            userNameList.pushArray(userNames);
          }
        }
        userNameList = _.uniq(userNameList);

        var deptWorkList = _.keys(detailObj);
        var search = this.search;
        if (deptWorkList.indexOf(search.deptWork) === -1) {
          search.deptWork = '';
        }

        this.deptWorkList = deptWorkList;
        this.userNameList = userNameList;
      },

      tableRunning: function () {
        var self = this;
        var timeout = setTimeout(function () {
          self.changeRowIndex();
          self.changeColIndex();
          self.tableRunning();
        }, 5000);
        this.timeoutList[0] = timeout;
      },

      changeRowIndex: function (hasResize) {
        var totalHeight = $(this.$refs['attendanceContent']).height();
        var tableHeight = $(this.$refs['attendanceTable']).height();
        tableHeight = Math.ceil(tableHeight);
        if (totalHeight >= tableHeight) {
          this.rowIndex = 0;
          return;
        }

        if (hasResize) {
          return;
        }

        var rowIndex = this.rowIndex + 1;
        if (rowIndex >= this.searchDetailList.length) {
          rowIndex = 0;
        }
        this.rowIndex = rowIndex;
      },

      changeColIndex: function (hasResize) {
        var totalWidth = $(this.$refs['attendanceContent']).width();
        var tableWidth = $(this.$refs['attendanceTable']).width();
        tableWidth = Math.ceil(tableWidth);
        if (totalWidth >= tableWidth) {
          this.colIndex = 0;
          return;
        }

        if (hasResize) {
          return;
        }

        var colIndex = this.colIndex + 1;
        if (colIndex >= tableConfigs.length) {
          colIndex = 0;
        }
        this.colIndex = colIndex;
      },

      setAttendanceDetailObj: function () {
        this.attendanceDetailObj = this.getAttendanceDetailObj();
        this.setDropdownList();
      },

      getAttendanceDetailObj: function () {
        var data = this.data;
        var detailObj = {};
        var lateNameList = data.lateTimesPersonName;
        lateNameList = _.orderBy(lateNameList, ['userName'], ['asc']);
        for (var i = 0; i < lateNameList.length; i++) {
          var lateName = lateNameList[i];
          var detail = new AttendanceDetailModel(lateName, 'late');
          this.initDetailObj(detail, detailObj, 'late');
        }

        var earlyNameList = data.earlyTimesPersonName;
        earlyNameList = _.orderBy(earlyNameList, ['userName'], ['asc']);
        for (var i = 0; i < earlyNameList.length; i++) {
          var earlyName = earlyNameList[i];
          var detail = new AttendanceDetailModel(earlyName, 'early');
          this.initDetailObj(detail, detailObj, 'early');
        }

        var leaveNameList = data.leaveTimesPersonName;
        leaveNameList = _.orderBy(leaveNameList, ['userName'], ['asc']);
        for (var i = 0; i < leaveNameList.length; i++) {
          var leaveName = leaveNameList[i];
          var detail = new AttendanceDetailModel(leaveName, 'leave');
          this.initDetailObj(detail, detailObj, 'leave');
        }

        var lackNameList = data.lackTimesPersonName;
        lackNameList = _.orderBy(lackNameList, ['userName'], ['asc']);
        for (var i = 0; i < lackNameList.length; i++) {
          var lackName = lackNameList[i];
          var detail = new AttendanceDetailModel(lackName, 'lack');
          this.initDetailObj(detail, detailObj, 'lack');
        }

        return detailObj;
      },

      initDetailObj: function (detail, detailObj, type) {
        var deptWork = detail.deptWork;
        var groupDetail = detailObj[deptWork];
        if (groupDetail === undefined) {
          groupDetail = {
            deptWork: deptWork,
            late: [],
            early: [],
            leave: [],
            lack: []
          };
          detailObj[deptWork] = groupDetail;
        }
        groupDetail[type].push(detail);
      },

      getDetailFormList: function (list, index) {
        var obj = list[index];
        if (obj === undefined) {
          return null;
        }
        return obj;
      },

      searchData: function () {
        this.toSearchData();
      },

      toSearchData: function () {
        var detailObj = this.attendanceDetailObj;
        detailObj = _.cloneDeep(detailObj);

        var search = this.search;
        var deptWork = search.deptWork,
          userName = search.userName;
        var fields = ['early', 'late', 'leave', 'lack'];
        var detailList = [];
        for (var key in detailObj) {
          if (deptWork !== '') {
            if (key !== deptWork) {
              continue;
            }
          }

          var detail = detailObj[key];
          if (userName !== '') {
            for (var i = 0; i < fields.length; i++) {
              var field = fields[i];
              var attendanceList = detail[field];
              attendanceList = _.filter(attendanceList, function (obj) {
                var name = obj.userName;
                return name.indexOf(userName) !== -1;
              });
              detail[field] = attendanceList;
            }
          }

          var late = detail.late;
          var early = detail.early;
          var leave = detail.leave;
          var lack = detail.lack;
          var maxNum = Math.max(late.length, early.length, leave.length, lack.length);
          if (maxNum === 0) {
            continue;
          }

          for (var i = 0; i < maxNum; i++) {
            var obj = {
              deptWork: key,
              late: this.getDetailFormList(late, i),
              early: this.getDetailFormList(early, i),
              leave: this.getDetailFormList(leave, i),
              lack: this.getDetailFormList(lack, i),
            };
            detailList.push(obj);
          }
        }

        this.searchDetailList = detailList;

        this.clearTimeoutList();
        if (this.rowIndex === 0 && this.colIndex === 0) {
          this.setShowDetailList();
          this.resetConfigs();
        } else {
          this.rowIndex = 0;
          this.colIndex = 0;
        }
        this.boardRunning();
      },

      resetTable: function () {
        this.setShowDetailList();
        this.resetConfigs();
      },

      setShowDetailList: function () {
        var searchDetailList = this.searchDetailList;
        var rowIndex = this.rowIndex;
        var detailList = searchDetailList.slice(rowIndex);
        if (rowIndex !== 0) {
          detailList.pushArray(searchDetailList.slice(0, rowIndex));
        }

        var details = [];
        var preDeptWork = null;
        for (var i = 0; i < detailList.length; i++) {
          var detail = detailList[i];
          var deptWork = detail.deptWork;
          if (deptWork !== preDeptWork) {
            var obj = {
              deptWork: deptWork,
              data: [this.getTabeData(detail)]
            };
            details.push(obj);
            preDeptWork = deptWork;
          } else {
            var obj = details[details.length - 1];
            obj.data.push(this.getTabeData(detail));
          }
        }

        this.detailList = details;
      },

      resetConfigs: function () {
        var colIndex = this.colIndex;
        var configs = tableConfigs;
        var newConfigs = configs.slice(colIndex);
        var lastConfigs = configs.slice(0, colIndex);
        newConfigs.pushArray(lastConfigs);
        this.configs = newConfigs;
      },

      getTabeData: function (detail) {
        var obj = {
          early: this.getTextByField(detail, 'early'),
          late: this.getTextByField(detail, 'late'),
          leave: this.getTextByField(detail, 'leave'),
          lack: this.getTextByField(detail, 'lack')
        };
        return obj;
      },

      getTextByField: function (detail, field) {
        var obj = detail[field];
        if (obj === null) {
          return '';
        }
        return obj.getObject();
      },

      getTableStyle: function () {
        var zoom = this.zoom;
        var size = _.round(zoom * 14, 0);
        if (size < 12) {
          return {
            zoom: zoom
          };
        }
        return {
          fontSize: `${size}px`
        };
      }
    },

    components: {
      SysAutocomplete: SysAutocomplete
    },

    template: template
  };
}();
